package com.sangshen.ad_suyi_flutter_sdk;

import android.app.Activity;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.util.HashMap;
import java.util.Map;

import cn.admobiletop.adsuyi.ad.error.ADSuyiError;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.StandardMethodCodec;

public class AdInstanceManager {

    @NonNull
    Activity activity;

    @NonNull
    private final Map<Integer, FlutterAd> ads;
    @NonNull
    private final MethodChannel channel;

    AdInstanceManager(@NonNull Activity activity, @NonNull BinaryMessenger binaryMessenger, @NonNull MethodChannel channel) {
        this.activity = activity;
        this.ads = new HashMap<>();
        this.channel =
            new MethodChannel(binaryMessenger, "ad_suyi_sdk");
    }

    void setActivity(@NonNull Activity activity) {
        this.activity = activity;
    }

    void trackAd(@NonNull FlutterAd ad, int adId) {
        if (ads.get(adId) != null) {
            throw new IllegalArgumentException(
                    String.format("Ad for following adId already exists: %d", adId));
        }
        ads.put(adId, ad);
    }

    /**
     * 根据adId获取广告对象
     * @param adId
     * @return
     */
    @Nullable
    FlutterAd adForId(int adId) {
        return ads.get(adId);
    }

    @Nullable
    Integer adIdFor(@NonNull FlutterAd ad) {
        for (Integer adId : ads.keySet()) {
            if (ads.get(adId) == ad) {
                return adId;
            }
        }
        return null;
    }

    /**
     * 根据id释放广告
     * @param adId
     */
    void disposeAd(int adId) {
        if (!ads.containsKey(adId)) {
            return;
        }
        Object adObject = ads.get(adId);
        if (adObject instanceof FlutterDestroyableAd) {
            ((FlutterDestroyableAd) adObject).release();
        }
        ads.remove(adId);
    }

    /**
     * 清除所有广告
     */
    public void disposeAllAds() {
        for (Map.Entry<Integer, FlutterAd> entry : ads.entrySet()) {
            if (entry.getValue() != null && entry.getValue() instanceof FlutterDestroyableAd) {
                FlutterDestroyableAd destroyableAd = (FlutterDestroyableAd) entry.getValue();
                destroyableAd.release();
            }
        }
        ads.clear();
    }

    void onAdReceive(@NonNull FlutterAd ad) {
        Map<Object, Object> arguments = new HashMap<>();
        arguments.put("adId", adIdFor(ad));
        arguments.put("eventName", "onSucced");
        channel.invokeMethod("onSucced", arguments);
    }

    void onAdExpose(@NonNull FlutterAd ad) {
        Map<Object, Object> arguments = new HashMap<>();
        arguments.put("adId", adIdFor(ad));
        arguments.put("eventName", "onExposed");
        channel.invokeMethod("onExposed", arguments);
    }

    void onAdClick(@NonNull FlutterAd ad) {
        Map<Object, Object> arguments = new HashMap<>();
        arguments.put("adId", adIdFor(ad));
        arguments.put("eventName", "onClicked");
        channel.invokeMethod("onClicked", arguments);
    }

    void onAdClose(@NonNull FlutterAd ad) {
        Map<Object, Object> arguments = new HashMap<>();
        arguments.put("adId", adIdFor(ad));
        arguments.put("eventName", "onClosed");
        channel.invokeMethod("onClosed", arguments);
    }

    void onAdFailed(@NonNull FlutterAd ad, @NonNull ADSuyiError error) {
        Map<Object, Object> arguments = new HashMap<>();
        arguments.put("adId", adIdFor(ad));
        arguments.put("eventName", "onFailed");
        arguments.put("loadAdError", error.toString());
        channel.invokeMethod("onFailed", arguments);
    }

    void onAdReward(@NonNull FlutterAd ad) {
        Map<Object, Object> arguments = new HashMap<>();
        arguments.put("adId", adIdFor(ad));
        arguments.put("eventName", "onRewarded");
        channel.invokeMethod("onRewarded", arguments);
    }

    public void onNativeReceived(FlutterNativeAd ad, double adWidth, double adHeight) {
        Map<Object, Object> arguments = new HashMap<>();
        arguments.put("adId", adIdFor(ad));
        arguments.put("adViewId", adIdFor(ad));
        arguments.put("adWidth", adWidth);
        arguments.put("adHeight", adHeight);
        arguments.put("eventName", "onReceived");
        channel.invokeMethod("onReceived", arguments);
    }
}
